/*
 * mock_network.cpp
 *
 *  Created on: 03.06.2011
 *      Author: inkooboo
 */

#include "mock_network.hpp"

#include <boost/bind.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/shared_ptr.hpp>

static boost::shared_ptr<mock_network_t> inst;
static boost::mutex inst_guard_;

//thread safe singleton by double checked lock idiom
mock_network_t &mock_network_t::instance()
{
    if (!inst)
    {
        boost::mutex::scoped_lock g(inst_guard_);
        if (!inst)
        {
            inst.reset(new mock_network_t);
        }
    }

    return *inst;
}

void channel_t::send(const char * data, size_t size)
{
    data_.assign(data, size);

    mock_network_t::instance().get_svc().post(boost::bind(&channel_t::do_send, this));
}

void channel_t::do_send()
{
    on_data_(data_.c_str(), data_.length());
}

boost::shared_ptr<channel_t> &mock_network_t::get_channel(const std::string &channel_name)
{
    boost::mutex::scoped_lock g(guard_);

    channel_map_t::iterator it = channel_map_.find(channel_name);

    if (!(it->second))
    {
        it->second.reset(new channel_t);
    }

    return it->second;
}

boost::asio::io_service &mock_network_t::get_svc()
{
    return svc_;
}
